﻿#region File Description
/*-----------------------------------------------------------------------------
 * Class: EmployeeManager
 *
 *  // mediator pattern?
 *
 *
 * Notes: Employee will be a base class for specific employees, if we get there.
 -------------------------------------------------------------------------------*/
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using Cubezicles.UI;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;


namespace Cubezicles
{
    /// <summary>
    /// Holds all of the information about money, including costs of stuff, salary, check funds sufficient, etc.
    /// </summary>
    public class MoneyManager : DrawableGameComponent // will be drawable? should handle drawing the errors/warnings? draws the daily $$$ report
    {
        #region CostConstants
        //--- NeedObject costs ---//
        // other classes (i.e. the need objects) access these constants to set their own costs

        // Cost of pinball machine
        public const int CostPinball = 500;

        // Cost of vending machine
        public const int CostVendingMachine = 7000;

        // Cost of drink machine
        public const int CostDrinkMachine = 6000;

        // Cost to build bathroom
        public const int CostBathroom = 10000;

        //--- Employee costs ---//

        // Cost to hire an employee (hire bonus)
        public const int CostHireBonus = 2000;
        public const int CostHireBonusDev = 2000;
        public const int CostHireBonusLeadDev = 3000;
        public const int CostHireBonusSteve = 2500;
        public const int CostHireBonusSlacker = 900;
        public const int CostHireBonusUXDesigner = 2800;

        // Daily salary for employees (regardless of how many hours they actually work)
        public const int DailySalary = 150;

        public const int DailySalaryDev = 150; // applies to steve and slacker as well???maybe?
        public const int DailySalaryLeadDev = 250;
        public const int DailySalarySteve = 150;
        public const int DailySalarySlacker = 85;

        public const int DailySalaryUXDesigner = 300; // not yet implemented

        #endregion

        // Okay button
        Texture2D btn;

        SoundEffect successfulPurchase;
        const String SuccessfulPurchaseSound = "Sounds/kaching";

        public UI.MoneyManagerPane managerPane { get; private set; }

        // Boolean to keep from paying the employees every tick
        public bool reported = false;
        int prof, revenue, curExpense;
        public int dailyExpenses = 0; //Buying people and objects

        // Get the Game1 object stored by the base class
        private Game1 game1 { get { return (Game1)Game; } }

        // Initial funds for our company
        public const int InitialFunds = 20000;

        // Goal funds for our company - current 100,000 ***
        public const int GoalFunds = 50000; //100000;

        // The current funds that this company/player has
        public int CurrentFunds { get; private set; }

        // use for testing purposes, press M to add money to current funds to try and trigger goal completion
        public void TestingAddMoney(int amount) { CurrentFunds += amount;}
        // press N to remove money
        public void TestingRemoveMoney(int amount) { CurrentFunds -= amount;}

        public bool CheckReachedGoal()
        {
            return CurrentFunds >= GoalFunds;
        }

        // ---game was reset............***
        public void Reset()
        {
            CurrentFunds = InitialFunds;
            dailyExpenses = 0;
        }



        /// <summary>
        /// MoneyManager class constructor.
        /// </summary>
        public MoneyManager(Game1 game): base(game)
        {
            this.DrawOrder = (int)Game1.DisplayOrder.Menus;
            // Give the player a starting lump sum of money
            CurrentFunds = InitialFunds;

            managerPane = new MoneyManagerPane(game, this);
            game.Components.Add(managerPane);
        }

        protected override void LoadContent()
        {
            btn = Game.Content.Load<Texture2D>("UI/buttons");
            successfulPurchase = game1.Content.Load<SoundEffect>(SuccessfulPurchaseSound);
            base.LoadContent();
        }

        #region BuyingStuffMethods

        public bool Pay(int cost)
        {
            if (CurrentFunds >= cost)
            {
                if (successfulPurchase != null) successfulPurchase.Play();
                CurrentFunds -= cost;
                return true;
            }

            return false;
        }

        /// <summary>
        /// Check if we have enough to hire someone, and if so, deduct $$$
        /// </summary>
        /// <returns></returns>
        public bool BuyHireBonus(EmployeeManager.EmployeeType empType)
        {
            int bonuscost = 0;
            switch(empType)
            {
                case EmployeeManager.EmployeeType.Dev:
                    bonuscost = CostHireBonusDev;
                    break;
                case EmployeeManager.EmployeeType.LeadDev:
                    bonuscost = CostHireBonusLeadDev;
                    break;
                case EmployeeManager.EmployeeType.Slacker:
                    bonuscost = CostHireBonusSlacker;
                    break;
                case EmployeeManager.EmployeeType.Steve:
                    bonuscost = CostHireBonusSteve;
                    break;
                default:
                    bonuscost = CostHireBonus;
                    break;
            }

            if (CurrentFunds >= bonuscost)
            {
                if(successfulPurchase!= null) successfulPurchase.Play();
                CurrentFunds -= bonuscost;
                dailyExpenses -= bonuscost; // was in employee manager before for some reason?
                return true;
            }
            return false; // this will be called from object pane as if(buynewhirebonus) { add employee }
        }
        #endregion

        internal int PayAllEmployees()
        {
            // LINQ suggested revision by Refactor or whatever its called
            // Note that you will pay all employees, even if it sends you into debt!
            //sum+= DailySalary; when only had 1 possible salary
            return game1.EmployeeManager.Employees.Sum(employee => employee.Salary);
        }

        
        /// <summary>
        /// Returns how much you spent on people and objects
        /// </summary>
        public int GetExpenses()
        {
            if (!reported)
            {
                curExpense = dailyExpenses;
            }

            return curExpense;
        }

        /// <summary>
        /// Updates the current funds (called at end of day)
        /// </summary>
        public int UpdateCurrentFunds()
        {
            if (!reported)
            {
                // add daily revenue and subtract daily salary costs
                prof = GetDailyRevenue() - PayAllEmployees();
                CurrentFunds += prof;
            }

            return prof;
        }

    
        // displays report and updates current funds.... also does other "end of day stuff"... really this should all be in game....
        /// <summary>
        /// 
        /// </summary>
        public void DisplayEODReport()
        {
            managerPane.DisplayEODReport();
        }


        /// <summary>
        /// 
        /// </summary> //*******************************TODO: make revenue function better
        /// <returns></returns>
        internal int GetDailyRevenue()
        {
            // If we haven't already made the report, calculate total revenue
            if (!reported)
            {
                float totalTimeWorkedToday = 0;
                float totalQualityHoursMultiplier = 0;
                foreach (Employee emp in game1.EmployeeManager.Employees)
                {
                    // TODO: incorporate quality of work for each employee........
                    // totalTimeWorkedToday += emp.GetDailyTimeSpentWorking()*emp.QualityOfWork;
                    totalTimeWorkedToday += emp.GetDailyTimeSpentWorking();
                    totalQualityHoursMultiplier += emp.GetDailyTimeSpentWorking() * emp.QualityOfWork;
                }

                // arbitrary formula for determining end of day revenue....todo make better later***, add in quality of work
                //revenue = (int)(totalTimeWorkedToday * 20); //45);
                revenue = (int)(totalTimeWorkedToday + totalQualityHoursMultiplier) * 20;
            }

            return revenue;
        }


    }
}
